package com.cskaoyan.mall.pay.service.impl;

import com.alipay.api.response.AlipayTradeQueryResponse;
import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.order.dto.PayOrderSuccessRequest;
import com.cskaoyan.mall.order.dto.PayOrderSuccessResponse;
import com.cskaoyan.mall.pay.api.OrderPayApi;
import com.cskaoyan.mall.pay.constants.PayResultEnum;
import com.cskaoyan.mall.pay.constants.PayReturnCodeEnum;
import com.cskaoyan.mall.pay.dal.entitys.Payment;
import com.cskaoyan.mall.pay.dal.persistence.PaymentMapper;
import com.cskaoyan.mall.pay.dto.PaymentRequest;
import com.cskaoyan.mall.pay.dto.alipay.AlipayQueryRetResponse;
import com.cskaoyan.mall.pay.dto.alipay.AlipaymentResponse;
import com.cskaoyan.mall.pay.service.PayCoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @auther cskaoyan
 * @date 2022/6/22:11:33
 */
@Slf4j
@Service
public class PayCoreServiceImpl implements PayCoreService {

    @Autowired
    PayHelper payHelper;

    @Autowired
    PaymentMapper paymentMapper;

    @Autowired
    OrderPayApi orderPayApi;

    @Override
    public AlipaymentResponse aliPay(PaymentRequest request) {
        AlipaymentResponse alipaymentResponse = new AlipaymentResponse();
        try {
            request.requestCheck();
            //  1.  访问支付宝，获取支付二维码
            log.info("访问支付宝，获取支付二维码");
            String codeFileName = payHelper.test_trade_precreate(request);

            // 2. 如果获取支付二维码失败
            if (codeFileName == null) {
                log.error("如果获取支付二维码失败");
                alipaymentResponse.setCode(PayReturnCodeEnum.GET_CODE_FALIED.getCode());
                alipaymentResponse.setMsg(PayReturnCodeEnum.GET_CODE_FALIED.getMsg());
                return alipaymentResponse;
            }

            // 3. 向tb_payment插入一条记录，该记录中， 支付状态为TRADE_PROCESSING
            Payment payment = new Payment();
            payment.setStatus(PayResultEnum.TRADE_PROCESSING.toString());
            payment.setOrderId(request.getTradeNo());
            payment.setOrderAmount(request.getOrderFee());
            payment.setCreateTime(new Date());
            payment.setUpdateTime(new Date());
            payment.setPayWay(request.getPayChannel());
            int effectedRows = paymentMapper.insertSelective(payment);
            if (effectedRows != 1) {
                log.error("tb_payment插入失败！");
                throw new BizException("tb_payment插入失败！");
            }
            // 返回成功的响应
            alipaymentResponse.setQrCode(codeFileName);
            alipaymentResponse.setCode(PayReturnCodeEnum.SUCCESS.getCode());
            alipaymentResponse.setMsg(PayReturnCodeEnum.SUCCESS.getMsg());
        } catch (Exception e) {
            log.error("PayCoreServiceImpl.aliPay Occur Exception :" + e);
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(alipaymentResponse, e);
        }
        return alipaymentResponse;
    }

    @Transactional
    @Override
    public AlipayQueryRetResponse queryAlipayRet(PaymentRequest request) {
        AlipayQueryRetResponse response = new AlipayQueryRetResponse();
        try {
            request.requestCheck();
            // 查询
            String orderId = request.getTradeNo();
            AlipayTradeQueryResponse tradeQueryResponse = payHelper.test_trade_query(orderId);
            Payment payment = new Payment();
            Example example = new Example(Payment.class);
            example.createCriteria().andEqualTo("orderId", orderId);
            if (tradeQueryResponse != null) {
                // 1. 修改tb_payment支付状态 TRADE_SUCCESS， 支付成功时间，支付完成时间

                payment.setStatus(PayResultEnum.TRADE_SUCCESS.toString());
                payment.setPayNo(tradeQueryResponse.getTradeNo());
                payment.setPayerUid(Long.parseLong(tradeQueryResponse.getBuyerUserId()));
                payment.setPayerName(tradeQueryResponse.getBuyerLogonId());
                System.out.println(tradeQueryResponse);
                payment.setPayerAmount(new BigDecimal(tradeQueryResponse.getBuyerPayAmount()));
                payment.setPayWay(request.getPayChannel());
                payment.setPaySuccessTime(new Date());
                payment.setCompleteTime(new Date());
                payment.setUpdateTime(new Date());
                int effectedRows = paymentMapper.updateByExampleSelective(payment, example);
                if(effectedRows != 1){
                    log.error("修改支付信息失败！");
                    throw new BizException("修改支付信息失败！");
                }
                log.info("tb_payment插入成功 orderId {}", orderId);
                // 服务调用
                // 2. 修改订单状态为支付成功
                // 3. 修改库存，查询订单中包含的所有订单条目，根据订单条目扣减每一个商品的锁定库存

                PayOrderSuccessRequest payOrderSuccessRequest = new PayOrderSuccessRequest();
                payOrderSuccessRequest.setOrderId(orderId);
                PayOrderSuccessResponse payOrderSuccessResponse = orderPayApi.payOrderSuccess(payOrderSuccessRequest);
                if(PayReturnCodeEnum.SUCCESS.getCode().equals(payOrderSuccessResponse.getCode())){
                    response.setCode(PayReturnCodeEnum.SUCCESS.getCode());
                    response.setMsg(PayReturnCodeEnum.SUCCESS.getMsg());
                }else {
                    log.error("订单修改失败");
                    throw new BizException("修改订单失败！");
                }
            } else {
                // 1. 修改tb_payment支付状态 FAIL, 更新一下支付完成时间
                payment.setStatus(PayResultEnum.FAIL.toString());
                payment.setCompleteTime(new Date());
                payment.setUpdateTime(new Date());
                int effectedRows = paymentMapper.updateByExampleSelective(payment, example);
                if(effectedRows != 1){
                    log.error("修改支付信息失败！");
                    throw new BizException("修改支付信息失败！");
                }
                response.setCode(PayReturnCodeEnum.PAYMENT_PROCESSOR_FAILED.getCode());
                response.setMsg(PayReturnCodeEnum.PAYMENT_PROCESSOR_FAILED.getMsg());
            }
        }catch (Exception e){
            log.error("PayCoreServiceImpl.queryAlipayRet Occur Exception :" + e);
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }

        return response;
    }
}
